using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;
using System.Web;
using System.Collections;

namespace Pegasus.Web.UI
{
    /// <summary>
    /// A MultiView control that automaticallly selects the correct view.
    /// </summary>
    [ToolboxData( "<{0}:MultiViewEx runat=\"server\"></{0}:MultiViewEx>" ), ParseChildren( typeof( ViewEx ) )]
    public class MultiViewEx : MultiView
    {
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
        public delegate string ConditionDelegate();

        private ConditionDelegate selectedDelegate = null;
        private string selectedString = null;

        /// <summary>
        /// The condition to select views by delegate.  
        /// This overrides the ActiveViewIndex and SetActiveView if it is set.
        /// It is expected to return the condition to use and takes no arguments.
        /// </summary>
        [Bindable( true ), Category( "Behavior" ), DefaultValue( "" )]
        public ConditionDelegate SelectedDelegate
        {
            get
            {
                return selectedDelegate;
            }
            set
            {
                selectedDelegate = value;
            }
        }

        /// <summary>
        /// The condition to select views by string.  
        /// This overrides the ActiveViewIndex and SetActiveView if it is set.
        /// </summary>
        [Bindable( true ), Category( "Behavior" ), DefaultValue( "" )]
        public string SelectedString
        {
            get
            {
                return selectedString;
            }
            set
            {
                selectedString = value;
            }
        }

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Load"></see> event.
		/// </summary>
		/// <param name="e">The <see cref="T:System.EventArgs"></see> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            string condition = getCondition();
            if( !string.IsNullOrEmpty( condition ) )
            {
                bool foundView = false;
                foreach( ViewEx view in this.Controls )
                {
                    if( view.Condition == condition )
                    {
                        SetActiveView( (View) view );
                        foundView = true;
                        break;
                    }
                }

                if( !foundView )
                {
                    // No view meets the condition, so hide the control
                    this.Visible = false;
                }
            }
            else
            {
                throw new HttpException( "No valid selection is set." );
            }

            base.OnLoad( e );
        }

        private string getCondition()
        {
            if( selectedDelegate != null && selectedString != null )
            {
                throw new HttpException( "Both the SelectedDelegate and the SelectedString cannot be set." );
            }
            else if( selectedDelegate != null )
            {
                return selectedDelegate();
            }
            else
            {
                return selectedString;
            }
        }

		/// <summary>
		/// Notifies the <see cref="T:System.Web.UI.WebControls.MultiView"></see> control that an XML or HTML element was parsed, and adds the element to the <see cref="T:System.Web.UI.WebControls.ViewCollection"></see> collection of the <see cref="T:System.Web.UI.WebControls.MultiView"></see> control.
		/// </summary>
		/// <param name="obj">An <see cref="T:System.Object"></see> that represents the parsed element.</param>
		/// <exception cref="T:System.Web.HttpException">The specified <see cref="T:System.Object"></see> is not a <see cref="T:System.Web.UI.WebControls.View"></see> control. </exception>
        protected override void AddParsedSubObject( object obj )
        {
            if( obj is ViewEx )
            {
                this.Controls.Add( (Control) obj );
            }
            else if( !( obj is LiteralControl ) )
            {
                throw new HttpException( "MultiViewEx can only have ViewEx items." );
            }
        }
    }
}
